/*
 * redactor 自定义插件
 * */
import ReactDOM from 'react-dom';

// import OssUploader from 'widgets/OssUploader';
// import './iconStyle.scss';

(function($R) {
    const mimeTypes = {
        image: ['image/png', 'image/jpeg'],
        video: ['audio/mp3', 'audio/mpeg'],
        pdf: ['application/pdf'],
    };
    // 公用上传插件
    $R.add('plugin', 'upload', {
        init: function(app) {
            this.app = app;
        },
        build: function(id, url, callback, type = 'image') {
            const mimeType = mimeTypes[type];
            let uProps = {
                loaderId: 'reactor_loader',
                type: 'redactor',
                typeErrMessage: '文件格式错误',
                sizeLimit: 1000 * 1024 * 1024,
                sizeErrMessage: '文件太大',
                mimeType: mimeType,
            };
            this.app.plugin.upload.callback = callback;
            ReactDOM.render(
             
                // <OssUploader onComplete={(url, type) => {
                //           callback({ url, id, type: type });
                //       }}/>,
                // $(id).get(0)
            );
        },
    });
    // 上传音频
    $R.add('plugin', 'file_custom', {
        modals: {
            file_custom: `<div id="redactor-modal-file-upload"></div>`,
        },
        init: function(app) {
            this.app = app;
            this.opts = app.opts;
            this.lang = app.lang;
            this.block = app.block;
            this.toolbar = app.toolbar;
            this.module = app.module;
            this.plugin = app.plugin;
        },
        start: function() {
            let btnText = '上传音频';
            let $button = this.toolbar.addButton(btnText, {
                title: btnText,
                api: 'plugin.file_custom.open',
            });
            $button.setIcon('<i class="anticon anticon-cloud-upload-o"></i>');
        },
        open: function() {
            var options = {
                title: '上传音频',
                width: '600px',
                name: 'file_custom',
                handle: 'insert',
            };
            this.app.api('module.modal.build', options);
            this.plugin.upload.build(
                '#redactor-modal-file-upload',
                this.opts.fileUpload,
                this.insert.bind(this),
                'video'
            );
            $('#redactor-filename').val(this.app.selection.get().toString());
        },
        insert: function(json) {
            this.app.api('module.modal.close');
            if (typeof json.error !== 'undefined') {
                this.modal.close();
                return;
            }
            // 上传mp3 音频
            if (json.type === 'audio/mp3' || json.type === 'audio/mpeg') {
                // get
                let data = `<audio src=${
                    json.url
                } controls preload controlsList="nodownload">你的浏览器不支持</audio>&nbsp;`;
                let id = typeof json.id === 'undefined' ? '' : json.id;
                let type = typeof json.s3 === 'undefined' ? 'file' : 's3';
                this.app.insertion.insertNode(data);
                // callback
                this.app.storage.add({ type: type, node: $('audio')[0], url: json.url, id: id });
            } else {
                // 上传视频
                // get
                let data = `<video src=${
                    json.url
                } controls='controls'>你的浏览器不支持</video>&nbsp;`;

                let id = typeof json.id === 'undefined' ? '' : json.id;
                let type = typeof json.s3 === 'undefined' ? 'file' : 's3';
                // this.buffer.set()
                this.app.insertion.insertNode(data);
                // callback
                this.app.storage.add({ type: type, node: $('video')[0], url: json.url, id: id });
            }
            // $(document).ready(function(){
            //   $('#redactor-modal').remove()
            // });
        },
    });
    // 选择视频
    $R.add('plugin', 'selectTreeVideo_custom', {
        modals: {
            filecustom: '<div id="redactor-modal-file-upload"></div>',
        },
        init: function(app) {
            this.app = app;
            this.opts = app.opts;
            this.lang = app.lang;
            this.block = app.block;
            this.toolbar = app.toolbar;
            this.module = app.module;
            this.plugin = app.plugin;
        },
        start: function() {
            var $button = this.toolbar.addButton('选择视频', {
                title: '选择视频',
                api: 'plugin.selectTreeVideo_custom.show',
            });
            $button.setIcon('<i class="anticon anticon-select"></i>');
        },
        show: function() {
            // this.selection.save();
            // popupVideoCascaderByTree({
            //     onOk: () => {
            //         this.plugin.selectTreeVideo_custom.insert(this.url);
            //     },
            //     onChange: url => {
            //         this.url = url;
            //     },
            // });
        },
        insert: function(value) {
            // video后面加个空span才能删除
            let data = `<video src=${value} controls='controls'>你的浏览器不支持</video>&nbsp;`;
            this.app.insertion.insertNode(data);
        },
    });
    // 上传PDF
    $R.add('plugin', 'uploadPdf_custom', {
        modals: {
            uploadPdf: '<div id="redactor-modal-file-upload"></div>',
        },
        init: function(app) {
            this.app = app;
            this.opts = app.opts;
            this.lang = app.lang;
            this.block = app.block;
            this.toolbar = app.toolbar;
            this.module = app.module;
            this.plugin = app.plugin;
        },
        start: function() {
            let $button = this.toolbar.addButton('上传PDF', {
                title: '上传PDF',
                api: 'plugin.uploadPdf_custom.show',
            });
            $button.setIcon('<i class="anticon anticon-file-pdf"></i>');
        },
        show: function() {
            var options = {
                title: '上传PDF',
                width: '600px',
                name: 'uploadPdf',
                handle: 'insert',
            };
            this.app.api('module.modal.build', options);
            this.plugin.upload.build(
                '#redactor-modal-file-upload',
                this.opts.fileUpload,
                this.insert.bind(this),
                'pdf'
            );
            $('#redactor-filename').val(this.app.selection.get().toString());
        },
        insert: function(json) {
            // error callback
            if (typeof json.error !== 'undefined') {
                this.modal.close();
                // this.core.callback('fileUploadError', json);
                return;
            }
            this.app.api('module.modal.close');
            let data = `<iframe src=${PDF_VIEWER_API +
                encodeURIComponent(
                    json.url
                )} style='width: 100%; border: 1px solid #ececec; min-height: 80vh; margin-bottom: 10px;' />&nbsp;`;
            // insert
            this.app.insertion.insertNode(data);
        },
    });

    $R.add('plugin', 'image', {
        translations: {
            zh_cn: {
                caption: '说明',
                'image-position': '位置',
                link: '链接',
                none: '无',
                left: '居左',
                center: '居中',
                right: '居右',
            },
        },
        modals: {
            uploadPic: '<div id="redactor-modal-file-upload"></div>',
            imageedit:
                '<div class="redactor-modal-group"> \
            <div id="redactor-modal-image-preview" class="redactor-modal-side"></div> \
            <form action="" class="redactor-modal-area"> \
                <div class="form-item"> \
                    <label for="modal-image-title"> ## title ##</label> \
                    <input type="text" id="modal-image-title" name="title" /> \
                </div> \
                <div class="form-item"> \
                    <label for="modal-image-caption">## caption ##</label> \
                    <input type="text" id="modal-image-caption" name="caption" aria-label="## caption ##" /> \
                </div> \
                <div class="form-item form-item-align"> \
                    <label>## image-position ##</label> \
                    <select name="align" aria-label="## image-position ##"> \
                        <option value="none">## none ##</option> \
                        <option value="left">## left ##</option> \
                        <option value="center">## center ##</option> \
                        <option value="right">## right ##</option> \
                    </select> \
                </div> \
                <div class="form-item"> \
                    <label for="modal-image-url">## link ##</label> \
                    <input type="text" id="modal-image-url" name="url" aria-label="## link ##" /> \
                </div> \
                <div class="form-item"> \
                    <label class="checkbox"><input type="checkbox" name="target" aria-label="## link-in-new-tab ##"> ## link-in-new-tab ##</label> \
                </div> \
            </form> \
        </div>',
        },
        init: function(app) {
            this.app = app;
            this.opts = app.opts;
            this.lang = app.lang;
            this.caret = app.caret;
            this.utils = app.utils;
            this.editor = app.editor;
            this.storage = app.storage;
            this.component = app.component;
            this.inspector = app.inspector;
            this.insertion = app.insertion;
            this.selection = app.selection;
            this.toolbar = app.toolbar;
            this.plugin = app.plugin;

            // local
            this.justResized = false;
        },
        // messages
        oninsert: function() {
            this._observeImages();
        },
        start: function() {
            // storage observe
            this.storage.observeImages();

            // resize
            if (this.opts.imageResizable) {
                this.resizer = $R.create('image.resize', this.app);
            }

            // observe
            this._observeImages();
            let $button = this.toolbar.addButton('上传图片', {
                title: '上传图片',
                api: 'plugin.image.open',
            });
            $button.setIcon('<i class="re-icon-image"></i>');
        },
        ondropimage: function(e, files, clipboard) {
            if (!this.opts.imageUpload) return;

            // var options = {
            //     url: this.opts.imageUpload,
            //     event: (clipboard) ? false : e,
            //     files: files,
            //     name: 'uploadPic',
            //     data: this.opts.imageData,
            //     paramName: this.opts.imageUploadParam
            // };
            var options = {
                title: '上传图片',
                width: '600px',
                name: 'uploadPic',
                handle: 'insert',

                url: this.opts.imageUpload,
                event: clipboard ? false : e,
                files: files,
                data: this.opts.imageData,
                paramName: this.opts.imageUploadParam,
            };

            this.app.api('module.upload.send', options);
            // this.plugin.upload.build('#redactor-modal-file-upload', this.opts.fileUpload, this.insert.bind(this), 'image');
        },
        onstop: function() {
            if (this.resizer) this.resizer.stop();
        },
        onbottomclick: function() {
            this.insertion.insertToEnd(this.editor.getLastNode(), 'image');
        },
        onimageresizer: {
            stop: function() {
                if (this.resizer) this.resizer.hide();
            },
        },
        onsource: {
            open: function() {
                if (this.resizer) this.resizer.hide();
            },
            closed: function() {
                this._observeImages();
                if (this.resizer) this.resizer.rebuild();
            },
        },
        onupload: {
            complete: function() {
                this._observeImages();
            },
            uploadPic: {
                complete: function(response) {
                    this._insert(response);
                },
                error: function(response) {
                    this._uploadError(response);
                },
            },
            imageedit: {
                complete: function(response) {
                    this._change(response);
                },
                error: function(response) {
                    this._uploadError(response);
                },
            },
            imagedrop: {
                complete: function(response, e) {
                    this._insert(response, e);
                },
                error: function(response) {
                    this._uploadError(response);
                },
            },
            imagereplace: {
                complete: function(response) {
                    this._change(response, false);
                },
                error: function(response) {
                    this._uploadError(response);
                },
            },
        },
        onmodal: {
            uploadPic: {
                open: function($modal, $form) {
                    this._setUpload($form);
                },
            },
            imageedit: {
                open: function($modal, $form) {
                    this._setFormData($modal, $form);
                },
                opened: function($modal, $form) {
                    this._setFormFocus($form);
                },
                remove: function() {
                    this._remove(this.$image);
                },
                save: function($modal, $form) {
                    this._save($modal, $form);
                },
            },
        },
        onimage: {
            observe: function() {
                this._observeImages();
            },
            resized: function() {
                this.justResized = true;
            },
        },
        oncontextbar: function(e, contextbar) {
            if (this.justResized) {
                this.justResized = false;
                return;
            }

            var current = this.selection.getCurrent();
            var data = this.inspector.parse(current);

            if (!data.isFigcaption() && data.isComponentType('image')) {
                var node = data.getComponent();
                var buttons = {
                    edit: {
                        title: this.lang.get('edit'),
                        api: 'module.image.open',
                    },
                    remove: {
                        title: this.lang.get('delete'),
                        api: 'module.image.remove',
                        args: node,
                    },
                };

                contextbar.set(e, node, buttons);
            }
        },

        // public
        open: function() {
            this.$image = this._getCurrent();
            this.app.api('module.modal.build', this._getModalData());
            this.plugin.upload.build(
                '#redactor-modal-file-upload',
                this.opts.fileUpload,
                this.insert.bind(this),
                'image'
            );
        },
        insert: function(data) {
            this._insert(data);
        },
        remove: function(node) {
            this._remove(node);
        },

        // private
        _getModalData: function() {
            var modalData;
            if (this._isImage() && this.opts.imageEditable) {
                modalData = {
                    name: 'imageedit',
                    width: '800px',
                    title: this.lang.get('edit'),
                    handle: 'save',
                    commands: {
                        save: { title: this.lang.get('save') },
                        remove: { title: this.lang.get('delete'), type: 'danger' },
                        cancel: { title: this.lang.get('cancel') },
                    },
                };
            } else {
                modalData = {
                    name: 'uploadPic',
                    title: this.lang.get('image'),
                };
            }

            return modalData;
        },
        _isImage: function() {
            return this.$image;
        },
        _getCurrent: function() {
            var current = this.selection.getCurrent();
            var data = this.inspector.parse(current);

            return data.isComponentType('image') && data.isComponentActive()
                ? this.component.create('image', data.getComponent())
                : false;
        },
        _insert: function(response, e) {
            this.app.api('module.modal.close');
            if (Array.isArray(response)) {
                var obj = {};
                for (var i = 0; i < response.length; i++) {
                    obj = $R.extend(obj, response[i]);
                }

                response = obj;
            } else if (typeof response === 'string') {
                response = { file: { url: response } };
            }

            if (typeof response === 'object') {
                var multiple = Object.keys(response).length > 1;
                this._insertSingle(response, e);
            }
        },
        _insertSingle: function(response, e) {
            for (var key in response) {
                var $img = this._createImageAndStore(response);
                var inserted = e
                    ? this.insertion.insertToPoint(e, $img)
                    : this.insertion.insertHtml($img);

                this._removeSpaceBeforeFigure(inserted[0]);

                // set is active
                this.component.setActive(inserted[0]);
                this.app.broadcast('image.uploaded', inserted[0], response);
            }
        },
        _createImageAndStore: function(item) {
            var $img = this.component.create('image');

            $img.addClass('redactor-uploaded-figure');
            $img.setData({
                src: item.url,
                id: item.id ? item.id : this.utils.getRandomId(),
            });

            // add to storage
            this.storage.add('image', $img.getElement());

            return $img;
        },
        _removeSpaceBeforeFigure: function(img) {
            if (!img) return;

            var prev = img.previousSibling;
            if (prev) {
                this._removeInvisibleSpace(prev);
                this._removeInvisibleSpace(prev.previousSibling);
            }
        },
        _removeInvisibleSpace: function(el) {
            if (el && el.nodeType === 3 && this.utils.searchInvisibleChars(el.textContent) !== -1) {
                el.parentNode.removeChild(el);
            }
        },
        _save: function($modal, $form) {
            var data = $form.getData();
            var imageData = {
                title: data.title,
                link: { url: data.url, target: data.target },
            };

            if (this.opts.imageCaption) imageData.caption = data.caption;
            if (this.opts.imagePosition) imageData.align = data.align;

            this.$image.setData(imageData);
            if (this.resizer) this.resizer.rebuild();

            this.app.broadcast('image.changed', this.$image);
            this.app.api('module.modal.close');
        },
        _change: function(response, modal) {
            if (typeof response === 'string') {
                response = { file: { url: response } };
            }

            if (typeof response === 'object') {
                var $img;
                for (var key in response) {
                    $img = $R.dom('<img>');
                    $img.attr('src', response[key].url);

                    this.$image.changeImage(response[key]);

                    this.app.broadcast('image.changed', this.$image, response);
                    this.app.broadcast('image.uploaded', this.$image, response);

                    break;
                }

                if (modal !== false) {
                    $img.on(
                        'load',
                        function() {
                            this.$previewBox.html($img);
                        }.bind(this)
                    );
                }
            }
        },
        _uploadError: function(response) {
            this.app.broadcast('image.uploadError', response);
        },
        _remove: function(node) {
            this.app.api('module.modal.close');
            this.component.remove(node);
        },
        _observeImages: function() {
            var $editor = this.editor.getElement();
            var self = this;
            $editor.find('img').each(function(node) {
                var $node = $R.dom(node);

                $node.off('.drop-to-replace');
                $node.on('dragover.drop-to-replace dragenter.drop-to-replace', function(e) {
                    e.preventDefault();
                    return;
                });

                $node.on('drop.drop-to-replace', function(e) {
                    if (!self.app.isDragComponentInside()) {
                        return self._setReplaceUpload(e, $node);
                    }
                });
            });
        },
        _setFormData: function($modal, $form) {
            this._buildPreview();
            this._buildPreviewUpload();

            var imageData = this.$image.getData();
            var data = {
                title: imageData.title,
            };

            // caption
            if (this.opts.imageCaption) data.caption = imageData.caption;
            else $modal.find('.form-item-caption').hide();

            // position
            if (this.opts.imagePosition) data.align = imageData.align;
            else $modal.find('.form-item-align').hide();

            if (imageData.link) {
                data.url = imageData.link.url;
                if (imageData.link.target) data.target = true;
            }

            $form.setData(data);
        },
        _setFormFocus: function($form) {
            $form.getField('title').focus();
        },
        _setReplaceUpload: function(e, $node) {
            e = e.originalEvent || e;
            e.stopPropagation();
            e.preventDefault();

            if (!this.opts.imageUpload) return;

            this.$image = this.component.create('image', $node);

            var options = {
                url: this.opts.imageUpload,
                files: e.dataTransfer.files,
                name: 'imagereplace',
                data: this.opts.imageData,
                paramName: this.opts.imageUploadParam,
            };

            this.app.api('module.upload.send', options);

            return;
        },
        _setUpload: function($form) {
            var options = {
                url: this.opts.imageUpload,
                element: $form.getField('file'),
                name: 'image',
                data: this.opts.imageData,
                paramName: this.opts.imageUploadParam,
            };

            this.app.api('module.upload.build', options);
        },
        _buildPreview: function() {
            this.$preview = $R.dom('#redactor-modal-image-preview');
            this.$image = this._getCurrent();
            var imageData = this.$image.getData();
            var $previewImg = $R.dom('<img>');
            $previewImg.attr('src', imageData.src);

            this.$previewBox = $R.dom('<div>');
            this.$previewBox.append($previewImg);

            this.$preview.html('');
            this.$preview.append(this.$previewBox);
        },
        _buildPreviewUpload: function() {
            if (!this.opts.imageUpload) return;

            var $desc = $R.dom('<div class="desc">');
            $desc.html(this.lang.get('upload-change-label'));

            this.$preview.append($desc);

            var options = {
                url: this.opts.imageUpload,
                element: this.$previewBox,
                name: 'imageedit',
                paramName: this.opts.imageUploadParam,
            };

            this.app.api('module.upload.build', options);
        },
    });


    $R.add('plugin', 'insertLine4', {
        init: function(app) {
            this.app = app;
            this.toolbar = app.toolbar;
        },
        start: function() {
            var buttonData = {
                title: '插入4条下划线',
                icon: '<div style="width: 16px;height: 16px" />',
                api: 'plugin.insertLine4.insert',
            };
            var $button = this.toolbar.addButton('insertLine4', buttonData);
        },
        insert: function() {
            let insertText = '&nbsp;____&nbsp;';
            this.app.insertion.insertText(insertText);
        },
    });

    $R.add('plugin', 'insertLine8', {
        init: function(app) {
            this.app = app;
            this.toolbar = app.toolbar;
        },
        start: function() {
            var buttonData = {
                title: '插入8条下划线',
                icon: '<div style="width: 16px;height: 16px" />',
                api: 'plugin.insertLine8.insert',
            };
            var $button = this.toolbar.addButton('insertLine8', buttonData);
        },
        insert: function() {
            let insertText = '&nbsp;________&nbsp;';
            this.app.insertion.insertText(insertText);
        },
    });

    //wordpaster
    $R.add('plugin', 'wordpaster', {
        init: function(app) {
            this.app = app;
            this.toolbar = app.toolbar;
        },
        start: function() {
            var buttonData = {
                title: 'Word一键粘贴',
                icon: '<img src="./static/WordPaster/css/word.png"/>',
                api: 'plugin.wordpaster.insert',
            };
            var $button = this.toolbar.addButton('wordpaster', buttonData);
        },
        insert: function() {
            WordPaster.getInstance().SetEditor(this.app.insertion).Paste();
        },
    });

    //wordtoimg
    $R.add('plugin', 'wordtoimg', {
        init: function(app) {
            this.app = app;
            this.toolbar = app.toolbar;
        },
        start: function() {
            var buttonData = {
                title: 'Word转图片',
                icon: '<img src="./static/WordPaster/css/word1.png"/>',
                api: 'plugin.wordtoimg.insert',
            };
            var $button = this.toolbar.addButton('wordtoimg', buttonData);
        },
        insert: function() {
            WordPaster.getInstance().SetEditor(this.app.insertion).importWordToImg();
        },
    });

    //netimg
    $R.add('plugin', 'netimg', {
        init: function(app) {
            this.app = app;
            this.toolbar = app.toolbar;
        },
        start: function() {
            var buttonData = {
                title: '网络图片一键上传',
                icon: '<img src="./static/WordPaster/css/net.png"/>',
                api: 'plugin.netimg.insert',
            };
            var $button = this.toolbar.addButton('netimg', buttonData);
        },
        insert: function() {
            WordPaster.getInstance().SetEditor(this.app.insertion).UploadNetImg();
        },
    });

    //wordimport
    $R.add('plugin', 'wordimport', {
        init: function(app) {
            this.app = app;
            this.toolbar = app.toolbar;
        },
        start: function() {
            var buttonData = {
                title: '导入Word文档',
                icon: '<img src="./static/WordPaster/css/word2.png"/>',
                api: 'plugin.wordimport.insert',
            };
            var $button = this.toolbar.addButton('wordimport', buttonData);
        },
        insert: function() {
            WordPaster.getInstance().SetEditor(this.app.insertion).importWord();
        },
    });

    //excelimport
    $R.add('plugin', 'excelimport', {
        init: function(app) {
            this.app = app;
            this.toolbar = app.toolbar;
        },
        start: function() {
            var buttonData = {
                title: '导入Excel文档',
                icon: '<img src="./static/WordPaster/css/ppt.png"/>',
                api: 'plugin.wordpaster.insert',
            };
            var $button = this.toolbar.addButton('wordpaster', buttonData);
        },
        insert: function() {
            WordPaster.getInstance().SetEditor(this.app.insertion).importExcel();
        },
    });

    //pptimport
    $R.add('plugin', 'pptimport', {
        init: function(app) {
            this.app = app;
            this.toolbar = app.toolbar;
        },
        start: function() {
            var buttonData = {
                title: '导入PPT文档',
                icon: '<img src="./static/WordPaster/css/ppt.png"/>',
                api: 'plugin.wordpaster.insert',
            };
            var $button = this.toolbar.addButton('wordpaster', buttonData);
        },
        insert: function() {
            WordPaster.getInstance().SetEditor(this.app.insertion).importPPT();
        },
    });

    //pdfimport
    $R.add('plugin', 'pdfimport', {
        init: function(app) {
            this.app = app;
            this.toolbar = app.toolbar;
        },
        start: function() {
            var buttonData = {
                title: '导入PDF文档',
                icon: '<img src="./static/WordPaster/css/pdf.png"/>',
                api: 'plugin.pdfimport.insert',
            };
            var $button = this.toolbar.addButton('wordpaster', buttonData);
        },
        insert: function() {
            WordPaster.getInstance().SetEditor(this.app.insertion).ImportPDF();
        },
    });

})(Redactor);
